/*
Copyright 2024.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package controller

import (
	"context"
	"fmt"
	"github.com/go-logr/logr"
	nancaldevelopv1beta1 "github.com/lecang-installer/api/v1beta1"
	"github.com/lecang-installer/internal/utils"
	appsv1 "k8s.io/api/apps/v1"
	v1 "k8s.io/api/apps/v1"
	corev1 "k8s.io/api/core/v1"
	rbacv1 "k8s.io/api/rbac/v1"
	storagev1 "k8s.io/api/storage/v1"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/types"
	"reflect"
	ctrl "sigs.k8s.io/controller-runtime"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
	"sigs.k8s.io/controller-runtime/pkg/log"
)

// InstallerReconciler reconciles a Installer object
type InstallerReconciler struct {
	client.Client
	Scheme *runtime.Scheme
}

// +kubebuilder:rbac:groups=nancaldevelop.nancal.com,resources=installers,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=nancaldevelop.nancal.com,resources=installers/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=nancaldevelop.nancal.com,resources=installers/finalizers,verbs=update
// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups="",resources=services,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups="",resources=pods,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups="",resources=serviceaccounts,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups="",resources=persistentvolumeclaims,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups="",resources=persistentvolumeclaims,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups="",resources=persistentvolumes,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups="storage.k8s.io",resources=storageclasses,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups="storage.k8s.io",resources=persistentvolumeclaims,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups="storage.k8s.io",resources=persistentvolumes,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources=roles,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources=rolebindings,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources=clusterroles,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources=clusterrolebindings,verbs=get;list;watch;create;update;patch;delete

// Reconcile is part of the main kubernetes reconciliation loop which aims to
// move the current state of the cluster closer to the desired state.
// TODO(user): Modify the Reconcile function to compare the state specified by
// the Installer object against the actual cluster state, and then
// perform operations to make the cluster state reflect the state specified by
// the user.
//
// For more details, check Reconcile and its Result here:
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.0/pkg/reconcile
func (r *InstallerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
	logger := log.FromContext(ctx)
	installer := &nancaldevelopv1beta1.Installer{}

	logger.WithName("installer").Info("Start reconcile ...")

	//从缓存中获取app
	if err := r.Get(ctx, req.NamespacedName, installer); err != nil {
		return ctrl.Result{}, client.IgnoreNotFound(err)

	}

	if err := r.Get(ctx, types.NamespacedName{Name: "nfs-client-provisioner", Namespace: installer.Namespace}, &appsv1.Deployment{}); err != nil {
		var resources []interface{}
		var resName string
		if errors.IsNotFound(err) {

			//config := utils.Config{
			//	Name: installer.Spec.NfsProvisioner.Name,
			//	Namespace: installer.Namespace,
			//	NfsServer: installer.Spec.NfsProvisioner.NfsServer,
			//	NfsPath:   installer.Spec.NfsProvisioner.NfsPath,
			//	PvcStorageClassName: installer.Spec.NfsProvisioner.PvcStorageClassName,
			//	StorageSize: installer.Spec.NfsProvisioner.StorageSize,
			//}
			if installer.Spec.NfsProvisioner.Enable {

				resources, err = r.CreateNfsResourcesHandle(installer, logger)
				if err != nil {
					logger.WithName("Operator Installer CreateNfsResourcesHandle "+resName).Error(err, "CreateNfsResourcesHandle failed...")
					return ctrl.Result{}, err
				}
				resName, err = r.CreateResourceHandle(ctx, resources, logger, installer)
				if err != nil {
					logger.WithName("Operator Installer CreateResourceHandle "+resName).Error(err, "CreateResourceHandle failed...")
					return ctrl.Result{}, err
				}
			} else {
				// create local-pv and pvc
				var resPv, resPvc []interface{}
				resPv, err = r.CreatePvResourceHandle(logger, installer)
				if err != nil {
					logger.WithName("Operator Installer CreatePvResourceHandle "+resName).Error(err, "CreatePvResourceHandle failed...")
					return ctrl.Result{}, err
				}
				resName, err = r.CreateResourceHandle(ctx, resPv, logger, installer)
				if err != nil {
					logger.WithName("Operator Installer CreateResourceHandle "+resName).Error(err, "CreateResourceHandle failed...")
					return ctrl.Result{}, err
				}

				//time.Sleep(time.Second * 5)
				pvStatus := make(map[string]bool)
				resPvc, err = r.CreatePvcResourceHandle(logger, installer)
				if err != nil {
					logger.WithName("Operator Installer CreatePvcResourceHandle "+resName).Error(err, "CreatePvcResourceHandle failed...")
					return ctrl.Result{}, err
				}
				for _, v := range resPv {
					pvIns := v.(*corev1.PersistentVolume)
					if err = r.Get(ctx, types.NamespacedName{Name: pvIns.Name, Namespace: pvIns.Namespace}, &corev1.PersistentVolume{}); err != nil {
						if errors.IsNotFound(err) {
							logger.WithName("Operator Installer Check PV "+pvIns.Name).Error(err, "Check PV "+pvIns.Name+"is not found")
							return ctrl.Result{}, err
						}
					} else {
						if pvIns.Status.Phase == "Available" || pvIns.Status.Phase == "Bound" {
							pvStatus[pvIns.Name] = true
						} else {
							pvStatus[pvIns.Name] = false
						}
					}
				}
				for k, v := range pvStatus {
					if v {
						logger.WithName("Operator Installer Check PV " + k).Info("PV is OK")
					} else {
						logger.WithName("Operator Installer Check PV "+k).Error(err, "Check PV "+k+"is not found")
						return ctrl.Result{}, err
					}
				}
				resName, err = r.CreateResourceHandle(ctx, resPvc, logger, installer)
				if err != nil {
					logger.WithName("Operator Installer CreateResourceHandle PVC "+resName).Error(err, "CreateResourceHandle failed...")
					return ctrl.Result{}, err
				}

			}

			///////
			//nfsProvisioner, err := utils.TemplateParseHandle(files.NfsClientProvisioner, config, "nfsProvisioner", logger)
			//if err != nil {
			//	return ctrl.Result{}, fmt.Errorf("TemplateParseHandle file nfsprovisioner.yaml failed %v\n", err)
			//}
			//pvc, err := utils.TemplateParseHandle(files.AllPvc, config, "nfsProvisioner", logger)
			//if err != nil {
			//	return ctrl.Result{}, fmt.Errorf("TemplateParseHandle file pvc.yaml failed %v\n", err)
			//}
			//
			//nfsfile, err := os.Create("/nfsprovisioner.yaml")
			//if err != nil {
			//	return ctrl.Result{}, fmt.Errorf("create file /nfsprovisioner.yaml failed %v\n", err)
			//}
			//pvcfile, err := os.Create("/pvc.yaml")
			//if err != nil {
			//	return ctrl.Result{}, fmt.Errorf("create file /pvc.yaml failed %v\n", err)
			//}
			//defer nfsfile.Close()
			//defer pvcfile.Close()
			//
			//_, err = nfsfile.Write(nfsProvisioner)
			//if err != nil {
			//	return ctrl.Result{}, fmt.Errorf("write file /nfsprovisioner.yaml failed %v\n", err)
			//}
			//_, err = pvcfile.Write(pvc)
			//if err != nil {
			//	return ctrl.Result{}, fmt.Errorf("write file /pvc.yaml failed %v\n", err)
			//}
			//
			//_, err = utils.RunSSHCommand("kubectl", "apply", "-f", "/nfsprovisioner.yaml")
			//if err != nil {
			//	return ctrl.Result{}, fmt.Errorf("RunSSHCommand kubectl apply -f /nfsprovisioner.yaml , failed %v\n", err)
			//}
			//
			//_, err = utils.RunSSHCommand("kubectl", "apply", "-f", "/pvc.yaml")
			//if err != nil {
			//	return ctrl.Result{}, fmt.Errorf("RunSSHCommand kubectl apply -f /pvc.yaml , failed %v\n", err)
			//}

		} else {
			logger.WithName("Operator Installer CreateResourceHandle "+resName).Error(err, "r.Get ResourceHandle failed...")
			return ctrl.Result{}, err
		}
	} else if !installer.Spec.NfsProvisioner.Enable {

		//_, err = utils.RunSSHCommand("kubectl", "delete", "-f", "/nfsprovisioner.yaml")
		//if err != nil {
		//	return ctrl.Result{}, fmt.Errorf("RunSSHCommand kubectl delete -f /nfsprovisioner.yaml , failed %v\n", err)
		//}
		logger.WithName("Installer Operator").Info("NFS-Client-Provisioner is not enable...,delete method TODO ")
	} else {
		logger.WithName("Installer Operator").Info("NFS-Client-Provisioner is Deployed ")
	}

	//根据app的配置进行处理
	//1. Deployment的处理
	logger.WithName("Installer Operator").Info("Handle CRD Resource...")
	res, err := utils.NewDeploy(installer, logger)
	if err != nil {
		return ctrl.Result{}, err
	}

	for _, v := range res {
		switch resource := v.(type) {
		case *appsv1.Deployment:
			desiredDeployment := *resource
			logger.WithName("Installer Operator ").Info("Handle Deployment " + resource.Name + "...")
			if err = controllerutil.SetControllerReference(installer, resource, r.Scheme); err != nil {
				return ctrl.Result{}, err
			}

			if err = r.Get(ctx, types.NamespacedName{Name: resource.Name, Namespace: resource.Namespace}, resource); err != nil {
				if errors.IsNotFound(err) {
					if err = r.Create(ctx, resource); err != nil {
						logger.Error(err, "create deploy failed")
						return ctrl.Result{}, err
					}
				}
			} else {
				//if err = controllerutil.SetControllerReference(installer, &newDeployment, r.Scheme); err != nil {
				//	return ctrl.Result{}, err
				//}
				// 在更新 Deployment 时，保留原有的 ownerReferences
				if !reflect.DeepEqual(resource.Spec, desiredDeployment.Spec) {
					resource.Spec = desiredDeployment.Spec
					if err = r.Update(ctx, resource); err != nil {
						return ctrl.Result{}, err
					}
				} else {
					logger.WithName("Reconcile Service " + resource.Name).Info(" Skip update")
				}
			}
		case *corev1.Service:
			desiredService := *resource
			logger.WithName("Installer Operator").Info("Handle Service " + resource.Name + "...")
			if err = controllerutil.SetControllerReference(installer, resource, r.Scheme); err != nil {
				return ctrl.Result{}, err
			}
			//查找指定service
			if err = r.Get(ctx, types.NamespacedName{Name: resource.Name, Namespace: resource.Namespace}, resource); err != nil {
				if errors.IsNotFound(err) {
					if err := r.Create(ctx, resource); err != nil {
						logger.Error(err, "create service failed")
						return ctrl.Result{}, err
					}
				}
				if !errors.IsNotFound(err) {
					return ctrl.Result{}, err
				}
			} else {
				//if installer.Spec.EnableService {
				//	logger.Info("skip update")
				//} else {
				//	if err := r.Delete(ctx, service); err != nil {
				//		return ctrl.Result{}, err
				//	}
				//}
				// 在更新 Srevice 时，保留原有的 ownerReferences
				if !reflect.DeepEqual(resource.Spec.Ports, desiredService.Spec.Ports) {
					resource.Spec.Ports = desiredService.Spec.Ports
					if err = r.Update(ctx, resource); err != nil {
						return ctrl.Result{}, err
					}
				} else {
					logger.WithName("Reconcile Service " + resource.Name).Info(" Skip update")
				}

			}
		case *corev1.ConfigMap:
			desiredConfigmap := *resource
			logger.WithName("Installer Operator ").Info("Handle Configmap...")
			if err = controllerutil.SetControllerReference(installer, resource, r.Scheme); err != nil {
				return ctrl.Result{}, err
			}
			//查找指定configmap
			if err = r.Get(ctx, types.NamespacedName{Name: resource.Name, Namespace: resource.Namespace}, resource); err != nil {
				if errors.IsNotFound(err) {
					if err := r.Create(ctx, resource); err != nil {
						logger.Error(err, "create Configmap failed")
						return ctrl.Result{}, err
					}
				}
				if !errors.IsNotFound(err) {
					return ctrl.Result{}, err
				}
			} else {
				//if installer.Spec.EnableService {
				//	logger.Info("skip update")
				//} else {
				//	if err := r.Delete(ctx, configmap); err != nil {
				//		return ctrl.Result{}, err
				//	}
				//}
				// 在更新 Srevice 时，保留原有的 ownerReferences
				if !reflect.DeepEqual(resource.Data, desiredConfigmap.Data) {
					resource.Data = desiredConfigmap.Data
					if err = r.Update(ctx, resource); err != nil {
						return ctrl.Result{}, err
					}
				} else {
					logger.WithName("Reconcile Configmap " + resource.Name).Info(" Skip update...")
				}

			}
		case *corev1.ServiceAccount:
			desiredServiceAccount := *resource
			logger.WithName("Installer Operator ").Info("Handle Configmap...")
			if err = controllerutil.SetControllerReference(installer, resource, r.Scheme); err != nil {
				return ctrl.Result{}, err
			}
			//查找指定configmap
			if err = r.Get(ctx, types.NamespacedName{Name: resource.Name, Namespace: resource.Namespace}, resource); err != nil {
				if errors.IsNotFound(err) {
					if err := r.Create(ctx, resource); err != nil {
						logger.Error(err, "create service failed")
						return ctrl.Result{}, err
					}
				}
				if !errors.IsNotFound(err) {
					return ctrl.Result{}, err
				}
			} else {
				//if installer.Spec.EnableService {
				//	logger.Info("skip update")
				//} else {
				//	if err := r.Delete(ctx, configmap); err != nil {
				//		return ctrl.Result{}, err
				//	}
				//}
				// 在更新 Srevice 时，保留原有的 ownerReferences
				if !reflect.DeepEqual(resource.Name, desiredServiceAccount.Name) {
					resource.Name = desiredServiceAccount.Name
					if err = r.Update(ctx, resource); err != nil {
						return ctrl.Result{}, err
					}
				} else {
					logger.WithName("Reconcile Configmap " + resource.Name).Info(" Skip update...")
				}

			}
		case *rbacv1.ClusterRole:
			desiredClusterRole := *resource
			logger.WithName("Installer Operator ").Info("Handle Configmap...")
			if err = controllerutil.SetControllerReference(installer, resource, r.Scheme); err != nil {
				return ctrl.Result{}, err
			}
			//查找指定configmap
			if err = r.Get(ctx, types.NamespacedName{Name: resource.Name, Namespace: resource.Namespace}, resource); err != nil {
				if errors.IsNotFound(err) {
					if err = r.Create(ctx, resource); err != nil {
						logger.Error(err, "create service failed")
						return ctrl.Result{}, err
					}
				}
				if !errors.IsNotFound(err) {
					return ctrl.Result{}, err
				}
			} else {
				//if installer.Spec.EnableService {
				//	logger.Info("skip update")
				//} else {
				//	if err := r.Delete(ctx, configmap); err != nil {
				//		return ctrl.Result{}, err
				//	}
				//}
				// 在更新 Srevice 时，保留原有的 ownerReferences
				if !reflect.DeepEqual(resource.Rules, desiredClusterRole.Rules) {
					resource.Rules = desiredClusterRole.Rules
					if err = r.Update(ctx, resource); err != nil {
						return ctrl.Result{}, err
					}
				} else {
					logger.WithName("Reconcile Configmap " + resource.Name).Info(" Skip update...")
				}

			}
		case *rbacv1.ClusterRoleBinding:
			desiredClusterRoleBinding := *resource
			logger.WithName("Installer Operator ").Info("Handle Configmap...")
			if err = controllerutil.SetControllerReference(installer, resource, r.Scheme); err != nil {
				return ctrl.Result{}, err
			}
			//查找指定resource
			if err = r.Get(ctx, types.NamespacedName{Name: resource.Name, Namespace: resource.Namespace}, resource); err != nil {
				if errors.IsNotFound(err) {
					if err = r.Create(ctx, resource); err != nil {
						logger.Error(err, "create service failed")
						return ctrl.Result{}, err
					}
				}
				if !errors.IsNotFound(err) {
					return ctrl.Result{}, err
				}
			} else {
				//if installer.Spec.EnableService {
				//	logger.Info("skip update")
				//} else {
				//	if err := r.Delete(ctx, configmap); err != nil {
				//		return ctrl.Result{}, err
				//	}
				//}
				// 在更新 Srevice 时，保留原有的 ownerReferences
				if !reflect.DeepEqual(resource.RoleRef, desiredClusterRoleBinding.RoleRef) &&
					!reflect.DeepEqual(resource.Subjects, desiredClusterRoleBinding.Subjects) {
					resource.RoleRef = desiredClusterRoleBinding.RoleRef
					resource.Subjects = desiredClusterRoleBinding.Subjects
					if err = r.Update(ctx, resource); err != nil {
						return ctrl.Result{}, err
					}
				} else {
					logger.WithName("Reconcile Configmap " + resource.Name).Info(" Skip update...")
				}

			}
		case *rbacv1.Role:
			desiredRole := *resource
			logger.WithName("Installer Operator ").Info("Handle Configmap...")
			if err = controllerutil.SetControllerReference(installer, resource, r.Scheme); err != nil {
				return ctrl.Result{}, err
			}
			//查找指定configmap
			if err = r.Get(ctx, types.NamespacedName{Name: resource.Name, Namespace: resource.Namespace}, resource); err != nil {
				if errors.IsNotFound(err) {
					if err = r.Create(ctx, resource); err != nil {
						logger.Error(err, "create service failed")
						return ctrl.Result{}, err
					}
				}
				if !errors.IsNotFound(err) {
					return ctrl.Result{}, err
				}
			} else {
				//if installer.Spec.EnableService {
				//	logger.Info("skip update")
				//} else {
				//	if err := r.Delete(ctx, configmap); err != nil {
				//		return ctrl.Result{}, err
				//	}
				//}
				// 在更新 Srevice 时，保留原有的 ownerReferences
				if !reflect.DeepEqual(resource.Rules, desiredRole.Rules) {
					resource.Rules = desiredRole.Rules
					if err = r.Update(ctx, resource); err != nil {
						return ctrl.Result{}, err
					}
				} else {
					logger.WithName("Reconcile Configmap " + resource.Name).Info(" Skip update...")
				}

			}
		case *rbacv1.RoleBinding:
			desiredRoleBinding := *resource
			logger.WithName("Installer Operator ").Info("Handle Configmap...")
			if err = controllerutil.SetControllerReference(installer, resource, r.Scheme); err != nil {
				return ctrl.Result{}, err
			}
			//查找指定resource
			if err = r.Get(ctx, types.NamespacedName{Name: resource.Name, Namespace: resource.Namespace}, resource); err != nil {
				if errors.IsNotFound(err) {
					if err = r.Create(ctx, resource); err != nil {
						logger.Error(err, "create service failed")
						return ctrl.Result{}, err
					}
				}
				if !errors.IsNotFound(err) {
					return ctrl.Result{}, err
				}
			} else {
				//if installer.Spec.EnableService {
				//	logger.Info("skip update")
				//} else {
				//	if err := r.Delete(ctx, configmap); err != nil {
				//		return ctrl.Result{}, err
				//	}
				//}
				// 在更新 Srevice 时，保留原有的 ownerReferences
				if !reflect.DeepEqual(resource.RoleRef, desiredRoleBinding.RoleRef) &&
					!reflect.DeepEqual(resource.Subjects, desiredRoleBinding.Subjects) {
					resource.RoleRef = desiredRoleBinding.RoleRef
					resource.Subjects = desiredRoleBinding.Subjects
					if err = r.Update(ctx, resource); err != nil {
						return ctrl.Result{}, err
					}
				} else {
					logger.WithName("Reconcile Configmap " + resource.Name).Info(" Skip update...")
				}

			}
		case *storagev1.StorageClass:
			desiredStorageClass := *resource
			logger.WithName("Installer Operator ").Info("Handle Configmap...")
			if err = controllerutil.SetControllerReference(installer, resource, r.Scheme); err != nil {
				return ctrl.Result{}, err
			}
			//查找指定configmap
			if err = r.Get(ctx, types.NamespacedName{Name: resource.Name, Namespace: resource.Namespace}, resource); err != nil {
				if errors.IsNotFound(err) {
					if err = r.Create(ctx, resource); err != nil {
						logger.Error(err, "create service failed")
						return ctrl.Result{}, err
					}
				}
				if !errors.IsNotFound(err) {
					return ctrl.Result{}, err
				}
			} else {
				//if installer.Spec.EnableService {
				//	logger.Info("skip update")
				//} else {
				//	if err := r.Delete(ctx, configmap); err != nil {
				//		return ctrl.Result{}, err
				//	}
				//}
				// 在更新 Srevice 时，保留原有的 ownerReferences
				if !reflect.DeepEqual(resource.Name, desiredStorageClass.Name) {
					resource.Name = desiredStorageClass.Name
					if err = r.Update(ctx, resource); err != nil {
						return ctrl.Result{}, err
					}
				} else {
					logger.WithName("Reconcile Configmap " + resource.Name).Info(" Skip update...")
				}

			}
		default:
			return ctrl.Result{}, fmt.Errorf("Do Not support type...")
		}
	}
	//2. Service的处理
	//svcs, err := utils.NewService(installer)
	//for _, svc := range svcs {
	//	switch s := svc.(type) {
	//	case *corev1.Service:
	//		if err = controllerutil.SetControllerReference(installer, s, r.Scheme); err != nil {
	//			return ctrl.Result{}, err
	//		}
	//		//查找指定service
	//		service := &corev1.Service{}
	//		ss := svc.(*corev1.Service)
	//		if err = r.Get(ctx, types.NamespacedName{Name: ss.Name, Namespace: ss.Namespace}, service); err != nil {
	//			if errors.IsNotFound(err) && installer.Spec.EnableService {
	//				if err := r.Create(ctx, ss); err != nil {
	//					logger.Error(err, "create service failed")
	//					return ctrl.Result{}, err
	//				}
	//			}
	//			if !errors.IsNotFound(err) && installer.Spec.EnableService {
	//				return ctrl.Result{}, err
	//			}
	//		} else {
	//			if installer.Spec.EnableService {
	//				logger.Info("skip update")
	//			} else {
	//				if err := r.Delete(ctx, service); err != nil {
	//					return ctrl.Result{}, err
	//				}
	//
	//			}
	//		}
	//
	//	default:
	//		fmt.Println("other type")
	//	}

	//}

	return ctrl.Result{}, nil
}

func (r *InstallerReconciler) CreateNfsResourcesHandle(installer *nancaldevelopv1beta1.Installer, logger logr.Logger) ([]interface{}, error) {
	var nfsResources []interface{}
	var ok bool
	var err error
	// parse serviceaccount
	//var nfsSA, nfsR, nfsRB, nfsDep, nfsSC, nfsPvc []byte
	//var scObj, pvcObj, saObj, roleObj, rbObj, depObj metav1.Object
	var nfsSA, nfsCR, nfsCRB, nfsR, nfsRB, nfsDep, nfsSC, nfsPvc []byte
	var scObj, pvcObj, saObj, crObj, crbObj, roleObj, rbObj, depObj metav1.Object
	nfsSA, err = utils.TemplateParseNfsServiceAccount(installer.Spec.NfsProvisioner.Name, logger, installer)
	if err != nil {
		return nil, fmt.Errorf("TemplateParseNfsServiceAccount failed %v\n", err)
	}
	nfsCR, err = utils.TemplateNfsParseClusterRole(installer.Spec.NfsProvisioner.Name, logger, installer)
	if err != nil {
		return nil, fmt.Errorf("TemplateNfsParseClusterRole failed %v\n", err)
	}
	nfsCRB, err = utils.TemplateParseNfsClusterRoleBinding(installer.Spec.NfsProvisioner.Name, logger, installer)
	if err != nil {
		return nil, fmt.Errorf("TemplateParseNfsClusterRoleBinding failed %v\n", err)
	}
	nfsR, err = utils.TemplateParseNfsRoleLeader(installer.Spec.NfsProvisioner.Name, logger, installer)
	if err != nil {
		return nil, fmt.Errorf("TemplateParseNfsRoleLeader failed %v\n", err)
	}
	nfsRB, err = utils.TemplateParseNfsRoleBindingLeader(installer.Spec.NfsProvisioner.Name, logger, installer)
	if err != nil {
		return nil, fmt.Errorf("TemplateParseNfsRoleBindingLeader failed %v\n", err)
	}
	nfsDep, err = utils.TemplateParseNfsDeployment(installer.Spec.NfsProvisioner.Name, logger, installer)
	if err != nil {
		return nil, fmt.Errorf("TemplateParseNfsDeployment failed %v\n", err)
	}

	for _, v := range installer.Spec.NfsProvisioner.StorageClassNames {
		nfsSC, err = utils.TemplateParseNfsStorageClass(installer.Spec.NfsProvisioner.Name, v, logger, installer)
		if err != nil {
			return nil, fmt.Errorf("TemplateParseNfsStorageClass failed %v\n", err)
		}
		var sc = &storagev1.StorageClass{}
		scObj, err = utils.YamlUnmarshalHandle(nfsSC, sc, logger)
		if err != nil {
			logger.WithName("Installer SA yamlUnmarshalHandle "+sc.Name).Error(err, " Deployment YAML Unmarshal to JSON failed")
			return nil, fmt.Errorf("YamlUnmarshalHandle %s failed %v\n", "SA: "+sc.Name, err)
		}
		if sc, ok = scObj.(*storagev1.StorageClass); !ok {
			logger.WithName("Operator Installer ").Error(err, "*v13.StorageClass failed!")
		}

		nfsResources = append(nfsResources, sc)

	}
	for _, v := range installer.Spec.NfsProvisioner.PvcNames {
		nfsPvc, err = utils.TemplateParseNfsPvc(installer.Spec.NfsProvisioner.Name, installer.Spec.NfsProvisioner.PvcStorageClassName, v, logger, installer)
		if err != nil {
			return nil, fmt.Errorf("TemplateParseNfsPvc failed %v\n", err)
		}
		var pvc = &corev1.PersistentVolumeClaim{}
		pvcObj, err = utils.YamlUnmarshalHandle(nfsPvc, pvc, logger)
		if err != nil {
			logger.WithName("Installer SA yamlUnmarshalHandle "+pvc.Name).Error(err, " Deployment YAML Unmarshal to JSON failed")
			return nil, fmt.Errorf("YamlUnmarshalHandle %s failed %v\n", "SA: "+pvc.Name, err)
		}
		if pvc, ok = pvcObj.(*corev1.PersistentVolumeClaim); !ok {
			logger.WithName("Operator Installer ").Error(err, "*corev1.PersistentVolumeClaim failed!")
		}

		nfsResources = append(nfsResources, pvc)
	}

	var sa = &corev1.ServiceAccount{}
	saObj, err = utils.YamlUnmarshalHandle(nfsSA, sa, logger)
	if err != nil {
		logger.WithName("Installer SA yamlUnmarshalHandle "+sa.Name).Error(err, " Deployment YAML Unmarshal to JSON failed")
		return nil, fmt.Errorf("YamlUnmarshalHandle %s failed %v\n", "SA: "+sa.Name, err)
	}
	if sa, ok = saObj.(*corev1.ServiceAccount); !ok {
		logger.WithName("Operator Installer ").Error(err, "*corev1.ServiceAccount failed!")
	}
	nfsResources = append(nfsResources, sa)

	var cr = &rbacv1.ClusterRole{}
	crObj, err = utils.YamlUnmarshalHandle(nfsCR, cr, logger)
	if err != nil {
		logger.WithName("Installer SA yamlUnmarshalHandle "+cr.Name).Error(err, " Deployment YAML Unmarshal to JSON failed")
		return nil, fmt.Errorf("YamlUnmarshalHandle %s failed %v\n", "SA: "+cr.Name, err)
	}
	if cr, ok = crObj.(*rbacv1.ClusterRole); !ok {
		logger.WithName("Operator Installer ").Error(err, "*v12.ClusterRole failed!")
	}
	nfsResources = append(nfsResources, cr)

	var crb = &rbacv1.ClusterRoleBinding{}
	crbObj, err = utils.YamlUnmarshalHandle(nfsCRB, crb, logger)
	if err != nil {
		logger.WithName("Installer SA yamlUnmarshalHandle "+crb.Name).Error(err, " Deployment YAML Unmarshal to JSON failed")
		return nil, fmt.Errorf("YamlUnmarshalHandle %s failed %v\n", "SA: "+crb.Name, err)
	}
	if crb, ok = crbObj.(*rbacv1.ClusterRoleBinding); !ok {
		logger.WithName("Operator Installer ").Error(err, "*v12.ClusterRoleBinding failed!")
	}
	nfsResources = append(nfsResources, crb)

	var role = &rbacv1.Role{}
	roleObj, err = utils.YamlUnmarshalHandle(nfsR, role, logger)
	if err != nil {
		logger.WithName("Installer SA yamlUnmarshalHandle "+role.Name).Error(err, " Deployment YAML Unmarshal to JSON failed")
		return nil, fmt.Errorf("YamlUnmarshalHandle %s failed %v\n", "SA: "+role.Name, err)
	}
	if role, ok = roleObj.(*rbacv1.Role); !ok {
		logger.WithName("Operator Installer ").Error(err, "*v12.Role failed!")
	}
	nfsResources = append(nfsResources, role)

	var rb = &rbacv1.RoleBinding{}
	rbObj, err = utils.YamlUnmarshalHandle(nfsRB, rb, logger)
	if err != nil {
		logger.WithName("Installer SA yamlUnmarshalHandle "+rb.Name).Error(err, " Deployment YAML Unmarshal to JSON failed")
		return nil, fmt.Errorf("YamlUnmarshalHandle %s failed %v\n", "SA: "+rb.Name, err)
	}
	if rb, ok = rbObj.(*rbacv1.RoleBinding); !ok {
		logger.WithName("Operator Installer ").Error(err, "*v12.RoleBinding failed!")
	}
	nfsResources = append(nfsResources, rb)

	var dep = &appsv1.Deployment{}
	depObj, err = utils.YamlUnmarshalHandle(nfsDep, dep, logger)
	if err != nil {
		logger.WithName("Installer SA yamlUnmarshalHandle "+dep.Name).Error(err, " Deployment YAML Unmarshal to JSON failed")
		return nil, fmt.Errorf("YamlUnmarshalHandle %s failed %v\n", "SA: "+dep.Name, err)
	}
	if dep, ok = depObj.(*appsv1.Deployment); !ok {
		logger.WithName("Operator Installer ").Error(err, "*appsv1.Deployment failed!")
	}
	nfsResources = append(nfsResources, dep)
	return nfsResources, nil
}

func (r *InstallerReconciler) CreateResourceHandle(ctx context.Context, resources []interface{}, logger logr.Logger, installer *nancaldevelopv1beta1.Installer) (string, error) {
	for _, v := range resources {

		switch resource := v.(type) {
		case *appsv1.Deployment:
			desiredDeployment := *resource
			logger.WithName("Installer Operator ").Info("Handle Deployment " + resource.Name + "...")
			//if err := controllerutil.SetControllerReference(installer, resource, r.Scheme); err != nil {
			//	return fmt.Errorf("resource:%s error: %v", resource.Name, err)
			//}

			if err := r.Get(ctx, types.NamespacedName{Name: resource.Name, Namespace: resource.Namespace}, resource); err != nil {
				if errors.IsNotFound(err) {
					if err = r.Create(ctx, resource); err != nil {
						logger.Error(err, "create deploy failed")
						return "Deployment" + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
					}
				}
			} else {
				// 在更新 Deployment 时，保留原有的 ownerReferences
				if !reflect.DeepEqual(resource.Spec, desiredDeployment.Spec) {
					resource.Spec = desiredDeployment.Spec
					if err = r.Update(ctx, resource); err != nil {
						return "Deployment" + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
					}
				} else {
					logger.WithName("Reconcile Service " + resource.Name).Info(" Skip update")
				}
			}
		case *corev1.Service:
			desiredService := *resource
			logger.WithName("Installer Operator").Info("Handle Service " + resource.Name + "...")
			//if err := controllerutil.SetControllerReference(installer, resource, r.Scheme); err != nil {
			//	return fmt.Errorf("resource:%s error: %v", resource.Name, err)
			//}
			//查找指定service
			if err := r.Get(ctx, types.NamespacedName{Name: resource.Name, Namespace: resource.Namespace}, resource); err != nil {
				if errors.IsNotFound(err) {
					if err = r.Create(ctx, resource); err != nil {
						logger.Error(err, "create service failed")
						return "Service" + resource.Name, fmt.Errorf("resource create %s error: %v", resource.Name, err)
					}
				}
				if !errors.IsNotFound(err) {
					return "Service" + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
				}
			} else {
				// 在更新 Srevice 时，保留原有的 ownerReferences
				if !reflect.DeepEqual(resource.Spec.Ports, desiredService.Spec.Ports) {
					resource.Spec.Ports = desiredService.Spec.Ports
					if err = r.Update(ctx, resource); err != nil {
						return "Service" + resource.Name, fmt.Errorf("resource update %s error: %v", resource.Name, err)
					}
				} else {
					logger.WithName("Reconcile Service " + resource.Name).Info(" Skip update")
				}
			}
		case *corev1.ConfigMap:
			desiredConfigmap := *resource
			logger.WithName("Installer Operator ").Info("Handle Configmap...")
			//if err := controllerutil.SetControllerReference(installer, resource, r.Scheme); err != nil {
			//	return fmt.Errorf("resource:%s error: %v", resource.Name, err)
			//}
			//查找指定configmap
			if err := r.Get(ctx, types.NamespacedName{Name: resource.Name, Namespace: resource.Namespace}, resource); err != nil {
				if errors.IsNotFound(err) {
					if err = r.Create(ctx, resource); err != nil {
						logger.Error(err, "create Configmap failed")
						return "ConfigMap" + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
					}
				}
				if !errors.IsNotFound(err) {
					return "ConfigMap" + resource.Name, fmt.Errorf("resource:%s Not Found error: %v", resource.Name, err)
				}
			} else {
				//if installer.Spec.EnableService {
				//	logger.Info("skip update")
				//} else {
				//	if err := r.Delete(ctx, configmap); err != nil {
				//		return ctrl.Result{}, err
				//	}
				//}
				// 在更新 Srevice 时，保留原有的 ownerReferences
				if !reflect.DeepEqual(resource.Data, desiredConfigmap.Data) {
					resource.Data = desiredConfigmap.Data
					if err = r.Update(ctx, resource); err != nil {
						return "ConfigMap" + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
					}
				} else {
					logger.WithName("Reconcile " + resource.Name).Info(" Skip update...")
				}

			}
		case *corev1.ServiceAccount:
			desiredServiceAccount := resource
			logger.WithName("Installer Operator ").Info("Handle ServiceAccount...")
			//if err := controllerutil.SetControllerReference(installer, resource, r.Scheme); err != nil {
			//	return fmt.Errorf("resource:%s error: %v", resource.Name, err)
			//}
			//查找指定configmap
			if err := r.Get(ctx, types.NamespacedName{Name: resource.Name, Namespace: resource.Namespace}, resource); err != nil {
				if errors.IsNotFound(err) {
					if err = r.Create(ctx, resource); err != nil {
						logger.Error(err, "create ServiceAccount failed")
						return "ServiceAccount" + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
					}
				}
				if !errors.IsNotFound(err) {
					return "ServiceAccount" + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
				}
			} else {
				//if installer.Spec.EnableService {
				//	logger.Info("skip update")
				//} else {
				//	if err := r.Delete(ctx, configmap); err != nil {
				//		return ctrl.Result{}, err
				//	}
				//}
				// 在更新 Srevice 时，保留原有的 ownerReferences
				if !reflect.DeepEqual(resource.Name, desiredServiceAccount.Name) {
					resource.Name = desiredServiceAccount.Name
					if err = r.Update(ctx, resource); err != nil {
						return "ServiceAccount" + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
					}
				} else {
					logger.WithName("Reconcile " + resource.Name).Info(" Skip update...")
				}

			}
		case *rbacv1.ClusterRole:
			desiredClusterRole := *resource
			logger.WithName("Installer Operator ").Info("Handle ClusterRole...")
			//查找指定configmap
			if err := r.Get(ctx, types.NamespacedName{Name: resource.Name, Namespace: resource.Namespace}, resource); err != nil {
				if errors.IsNotFound(err) {
					if err = r.Create(ctx, resource); err != nil {
						logger.Error(err, "create clusterrole failed")
						return "ClusterRole" + resource.Name, fmt.Errorf("resource: %s error: %v", resource.Name, err)
					}
				}
				if !errors.IsNotFound(err) {
					return "ClusterRole" + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
				}
			} else {
				//if installer.Spec.EnableService {
				//	logger.Info("skip update")
				//} else {
				//	if err := r.Delete(ctx, configmap); err != nil {
				//		return ctrl.Result{}, err
				//	}
				//}
				// 在更新 Srevice 时，保留原有的 ownerReferences
				if !reflect.DeepEqual(resource.Rules, desiredClusterRole.Rules) {
					resource.Rules = desiredClusterRole.Rules
					if err = r.Update(ctx, resource); err != nil {
						return "ClusterRole" + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
					}
				} else {
					logger.WithName("Reconcile " + resource.Name).Info(" Skip update...")
				}

			}
		case *rbacv1.ClusterRoleBinding:
			desiredClusterRoleBinding := *resource
			logger.WithName("Installer Operator ").Info("Handle ClusterRoleBinding...")
			//if err := controllerutil.SetControllerReference(installer, resource, r.Scheme); err != nil {
			//	return fmt.Errorf("resource:%s error: %v", resource.Name, err)
			//}
			//查找指定resource
			if err := r.Get(ctx, types.NamespacedName{Name: resource.Name, Namespace: resource.Namespace}, resource); err != nil {
				if errors.IsNotFound(err) {
					if err = r.Create(ctx, resource); err != nil {
						logger.Error(err, "create ClusterRoleBinding failed")
						return "ClusterRoleBinding " + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
					}
				}
				if !errors.IsNotFound(err) {
					return "ClusterRoleBinding " + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
				}
			} else {
				//if installer.Spec.EnableService {
				//	logger.Info("skip update")
				//} else {
				//	if err := r.Delete(ctx, configmap); err != nil {
				//		return ctrl.Result{}, err
				//	}
				//}
				// 在更新 Srevice 时，保留原有的 ownerReferences
				if !reflect.DeepEqual(resource.RoleRef, desiredClusterRoleBinding.RoleRef) &&
					!reflect.DeepEqual(resource.Subjects, desiredClusterRoleBinding.Subjects) {
					resource.RoleRef = desiredClusterRoleBinding.RoleRef
					resource.Subjects = desiredClusterRoleBinding.Subjects
					if err = r.Update(ctx, resource); err != nil {
						return "ClusterRoleBinding " + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
					}
				} else {
					logger.WithName("Reconcile " + resource.Name).Info(" Skip update...")
				}

			}
		case *rbacv1.Role:
			desiredRole := *resource
			logger.WithName("Installer Operator ").Info("Handle Role...")
			//if err := controllerutil.SetControllerReference(installer, resource, r.Scheme); err != nil {
			//	return fmt.Errorf("resource:%s error: %v", resource.Name, err)
			//}
			//查找指定configmap
			if err := r.Get(ctx, types.NamespacedName{Name: resource.Name, Namespace: resource.Namespace}, resource); err != nil {
				if errors.IsNotFound(err) {
					if err = r.Create(ctx, resource); err != nil {
						logger.Error(err, "create Role failed")
						return "Role " + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
					}
				}
				if !errors.IsNotFound(err) {
					return "Role " + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
				}
			} else {
				//if installer.Spec.EnableService {
				//	logger.Info("skip update")
				//} else {
				//	if err := r.Delete(ctx, configmap); err != nil {
				//		return ctrl.Result{}, err
				//	}
				//}
				// 在更新 Srevice 时，保留原有的 ownerReferences
				if !reflect.DeepEqual(resource.Rules, desiredRole.Rules) {
					resource.Rules = desiredRole.Rules
					if err = r.Update(ctx, resource); err != nil {
						return "Role " + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
					}
				} else {
					logger.WithName("Reconcile " + resource.Name).Info(" Skip update...")
				}

			}
		case *rbacv1.RoleBinding:
			desiredRoleBinding := *resource
			logger.WithName("Installer Operator ").Info("Handle RoleBinding...")
			//if err := controllerutil.SetControllerReference(installer, resource, r.Scheme); err != nil {
			//	return fmt.Errorf("resource:%s error: %v", resource.Name, err)
			//}
			//查找指定resource
			if err := r.Get(ctx, types.NamespacedName{Name: resource.Name, Namespace: resource.Namespace}, resource); err != nil {
				if errors.IsNotFound(err) {
					if err = r.Create(ctx, resource); err != nil {
						logger.Error(err, "create RoleBinding failed")
						return "RoleBinding " + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
					}
				}
				if !errors.IsNotFound(err) {
					return "RoleBinding " + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
				}
			} else {
				//if installer.Spec.EnableService {
				//	logger.Info("skip update")
				//} else {
				//	if err := r.Delete(ctx, configmap); err != nil {
				//		return ctrl.Result{}, err
				//	}
				//}
				// 在更新 Srevice 时，保留原有的 ownerReferences
				if !reflect.DeepEqual(resource.RoleRef, desiredRoleBinding.RoleRef) &&
					!reflect.DeepEqual(resource.Subjects, desiredRoleBinding.Subjects) {
					resource.RoleRef = desiredRoleBinding.RoleRef
					resource.Subjects = desiredRoleBinding.Subjects
					if err = r.Update(ctx, resource); err != nil {
						return "RoleBinding " + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
					}
				} else {
					logger.WithName("Reconcile " + resource.Name).Info(" Skip update...")
				}

			}
		case *storagev1.StorageClass:
			desiredStorageClass := *resource
			logger.WithName("Installer Operator ").Info("Handle StorageClass...")
			//查找指定configmap
			if err := r.Get(ctx, types.NamespacedName{Name: resource.Name, Namespace: resource.Namespace}, resource); err != nil {
				if errors.IsNotFound(err) {
					if err = r.Create(ctx, resource); err != nil {
						logger.Error(err, "create storageClass failed")
						return "StorageClass " + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
					}
				}
				if !errors.IsNotFound(err) {
					return "StorageClass " + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
				}
			} else {
				//if installer.Spec.EnableService {
				//	logger.Info("skip update")
				//} else {
				//	if err := r.Delete(ctx, configmap); err != nil {
				//		return ctrl.Result{}, err
				//	}
				//}
				// 在更新 Srevice 时，保留原有的 ownerReferences
				if !reflect.DeepEqual(resource.Name, desiredStorageClass.Name) {
					resource.Name = desiredStorageClass.Name
					if err = r.Update(ctx, resource); err != nil {
						return "StorageClass " + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
					}
				} else {
					logger.WithName("Reconcile StorageClass " + resource.Name).Info(" Skip update...")
				}

			}
		case *corev1.PersistentVolumeClaim:
			desiredPvc := *resource
			logger.WithName("Installer Operator ").Info("Handle PVC...")
			//查找指定pvc
			if err := r.Get(ctx, types.NamespacedName{Name: resource.Name, Namespace: resource.Namespace}, resource); err != nil {
				if errors.IsNotFound(err) {
					if err = r.Create(ctx, resource); err != nil {
						logger.Error(err, "create PVC failed")
						return "PersistentVolumeClaim " + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
					}
				}
				if !errors.IsNotFound(err) {
					return "PersistentVolumeClaim " + resource.Name, fmt.Errorf("resource:%s error: %v", resource.Name, err)
				}
			} else {
				//if installer.Spec.EnableService {
				//	logger.Info("skip update")
				//} else {
				//	if err := r.Delete(ctx, configmap); err != nil {
				//		return ctrl.Result{}, err
				//	}
				//}
				// 在更新 Srevice 时，保留原有的 ownerReferences
				if !reflect.DeepEqual(resource.Spec, desiredPvc.Spec) {
					logger.WithName("Reconcile PVC " + resource.Name).Info("new and old is equal")
				} else {
					logger.WithName("Reconcile PVC " + resource.Name).Info(" Skip update...")
				}

			}
		case *corev1.PersistentVolume:
			desiredPv := *resource
			logger.WithName("Installer Operator ").Info("Handle PV...")
			//查找指定pvc
			if err := r.Get(ctx, types.NamespacedName{Name: resource.Name, Namespace: resource.Namespace}, resource); err != nil {
				if errors.IsNotFound(err) {
					if err = r.Create(ctx, resource); err != nil {
						logger.Error(err, "create PV failed")
						return "PersistentVolume " + resource.Name, fmt.Errorf("resource create %s error: %v", resource.Name, err)
					}
				}
				if !errors.IsNotFound(err) {
					return "PersistentVolumeClaim " + resource.Name, fmt.Errorf("resource: %s error: %v", resource.Name, err)
				}
			} else {
				//if installer.Spec.EnableService {
				//	logger.Info("skip update")
				//} else {
				//	if err := r.Delete(ctx, configmap); err != nil {
				//		return ctrl.Result{}, err
				//	}
				//}
				// 在更新 Srevice 时，保留原有的 ownerReferences
				if !reflect.DeepEqual(resource.Spec, desiredPv.Spec) {
					logger.WithName("Reconcile PV " + resource.Name).Info("new and old is equal")
				} else {
					logger.WithName("Reconcile PV " + resource.Name).Info(" Skip update...")
				}

			}
		}
	}

	return "all resource complete !", nil
}

func (r *InstallerReconciler) CreatePvResourceHandle(logger logr.Logger, installer *nancaldevelopv1beta1.Installer) ([]interface{}, error) {
	var resources []interface{}
	var ok bool
	for _, v := range installer.Spec.Storage.PvNames {
		pvBytes, err := utils.TemplateParsePv("PV", v, logger, installer)
		if err != nil {
			return nil, fmt.Errorf("TemplateParseNfsDeployment failed %v\n", err)
		}
		var pv = &corev1.PersistentVolume{}
		pvObj, err := utils.YamlUnmarshalHandle(pvBytes, pv, logger)
		if err != nil {
			logger.WithName("Installer SA yamlUnmarshalHandle "+pv.Name).Error(err, " PV YAML Unmarshal to JSON failed")
			return nil, fmt.Errorf("YamlUnmarshalHandle %s failed %v\n", "PV: "+pv.Name, err)
		}
		if pv, ok = pvObj.(*corev1.PersistentVolume); !ok {
			logger.WithName("Operator Installer ").Error(err, "*corev1.PersistentVolume failed!")
		}
		resources = append(resources, pv)
	}
	return resources, nil

}

func (r *InstallerReconciler) CreatePvcResourceHandle(logger logr.Logger, installer *nancaldevelopv1beta1.Installer) ([]interface{}, error) {
	var resources []interface{}
	var ok bool
	for _, v := range installer.Spec.Storage.PvcNames {
		PvcBytes, err := utils.TemplateParsePvc("PVC", v, logger, installer)
		if err != nil {
			return nil, fmt.Errorf("TemplateParsePvc failed %v\n", err)
		}
		var pvc = &corev1.PersistentVolumeClaim{}
		pvcObj, err := utils.YamlUnmarshalHandle(PvcBytes, pvc, logger)
		if err != nil {
			logger.WithName("Installer PVC yamlUnmarshalHandle "+pvc.Name).Error(err, " PVC YAML Unmarshal to JSON failed")
			return nil, fmt.Errorf("YamlUnmarshalHandle %s failed %v\n", "PVC: "+pvc.Name, err)
		}
		if pvc, ok = pvcObj.(*corev1.PersistentVolumeClaim); !ok {
			logger.WithName("Operator Installer ").Error(err, "*corev1.PersistentVolumeClaim failed!")
			return nil, fmt.Errorf("assert *corev1.PersistentVolumeClaim %s failed %v\n", "PVC: "+pvc.Name, err)
		}

		resources = append(resources, pvc)
	}
	return resources, nil

}

// SetupWithManager sets up the controller with the Manager.
func (r *InstallerReconciler) SetupWithManager(mgr ctrl.Manager) error {
	return ctrl.NewControllerManagedBy(mgr).
		For(&nancaldevelopv1beta1.Installer{}).
		Owns(&v1.Deployment{}).
		Owns(&corev1.Service{}).
		Owns(&corev1.ConfigMap{}).
		Complete(r)
}
